package com.demo.algorithm.demo2;

/**
 * <p>
 * </p>
 * @author yanyg
 * @date 2024/2/15 17:43
 */
public class Philosopher extends Thread {
    private final int id;
    private final Chopstick leftChopstick;
    private final Chopstick rightChopstick;

    public Philosopher(int id, Chopstick leftChopstick, Chopstick rightChopstick) {
        this.id = id;
        this.leftChopstick = leftChopstick;
        this.rightChopstick = rightChopstick;
    }

    @Override
    public void run() {
        try {
            // 模拟思考
            Thread.sleep((long) (Math.random() * 1000));
            if (id % 2 == 0) {
                // 尝试获取左手边的筷子
                synchronized (leftChopstick) {
                    // 尝试获取右手边的筷子
                    synchronized (rightChopstick) {
                        // 吃饭
                        System.out.println("Philosopher " + id + " is eating.");
                        Thread.sleep((long) (Math.random() * 1000));
                    }
                }
            } else {
                // 尝试获取右手边的筷子
                synchronized (rightChopstick) {
                    // 尝试获取左手边的筷子
                    synchronized (leftChopstick) {
                        // 吃饭
                        System.out.println("Philosopher " + id + " is eating.");
                        Thread.sleep((long) (Math.random() * 1000));
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        int numPhilosophers = 5;
        Philosopher[] philosophers = new Philosopher[numPhilosophers];
        Chopstick[] chopsticks = new Chopstick[numPhilosophers];

        // 创建筷子
        for (int i = 0; i < numPhilosophers; i++) {
            chopsticks[i] = new Chopstick();
        }

        // 创建哲学家，并指定左右的筷子
        for (int i = 0; i < numPhilosophers; i++) {
            philosophers[i] = new Philosopher(i, chopsticks[i], chopsticks[(i + 1) % numPhilosophers]);
            philosophers[i].start();
        }
    }
}

